#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
B站视频下载器 - Tkinter版本主程序
现代化深色主题UI实现（使用Python内置GUI库）
"""

import sys
import os
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, scrolledtext
import threading
import time
import os
from pathlib import Path

# 导入核心模块
from core.bilibili_api import BilibiliAPI
from core.downloader import BilibiliDownloader, DownloadStatus
from core.utils import validate_bilibili_url, format_file_size, format_speed

class ModernDarkTheme:
    """
    现代化深色主题配色方案
    """
    # 主要颜色
    BACKGROUND = '#282c34'           # 深灰色背景
    CARD_BACKGROUND = '#3c4049'      # 卡片/控件背景色
    INPUT_BACKGROUND = '#4a4e57'     # 输入框背景色
    
    # 强调色
    PRIMARY = '#00a1d6'              # B站标志性蓝色
    PRIMARY_HOVER = '#0091c2'        # 主色悬停
    
    # 文本颜色
    TEXT_PRIMARY = '#ffffff'         # 主要文本（白色）
    TEXT_SECONDARY = '#b0b3b8'       # 次要文本（浅灰色）
    TEXT_DISABLED = '#6e7681'        # 禁用文本
    
    # 边框颜色
    BORDER = '#444c56'               # 默认边框
    BORDER_FOCUS = '#00a1d6'         # 焦点边框
    
    # 状态颜色
    SUCCESS = '#238636'              # 成功（绿色）
    WARNING = '#d29922'              # 警告（橙色）
    ERROR = '#da3633'                # 错误（红色）
    INFO = '#0969da'                 # 信息（蓝色）

class BilibiliDownloaderTk:
    """
    B站视频下载器主窗口类
    """
    
    def __init__(self):
        self.root = tk.Tk()
        
        # 核心组件
        self.api = BilibiliAPI()
        self.downloader = BilibiliDownloader()
        
        # 应用状态
        self.download_path = str(Path.home() / "Downloads" / "Bilibili")
        self.video_info = None
        self.is_downloading = False
        self.download_progress = 0
        self.current_task_id = None
        self.current_video_info = None
        
        # 创建下载目录
        os.makedirs(self.download_path, exist_ok=True)
        
        self.setup_window()
        self.create_widgets()
        self.setup_bindings()
        
    def setup_window(self):
        """
        设置主窗口属性
        """
        self.root.title("Bilibili 视频下载器")
        self.root.geometry("1000x750")
        self.root.minsize(900, 700)
        self.root.configure(bg=ModernDarkTheme.BACKGROUND)
        
        # 设置窗口居中
        self.center_window()
        
        # 配置样式
        self.setup_styles()
        
    def center_window(self):
        """
        窗口居中显示
        """
        self.root.update_idletasks()
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        x = (self.root.winfo_screenwidth() // 2) - (width // 2)
        y = (self.root.winfo_screenheight() // 2) - (height // 2)
        self.root.geometry(f"{width}x{height}+{x}+{y}")
        
    def setup_styles(self):
        """
        设置ttk样式
        """
        style = ttk.Style()
        
        # 配置主题
        style.theme_use('clam')
        
        # 配置各种控件样式
        style.configure('Dark.TFrame', 
                       background=ModernDarkTheme.BACKGROUND,
                       borderwidth=0)
        
        style.configure('Card.TFrame',
                       background=ModernDarkTheme.CARD_BACKGROUND,
                       relief='solid',
                       borderwidth=1,
                       bordercolor=ModernDarkTheme.BORDER)
        
        style.configure('Dark.TLabel',
                       background=ModernDarkTheme.BACKGROUND,
                       foreground=ModernDarkTheme.TEXT_PRIMARY,
                       font=('Microsoft YaHei', 10))
        
        style.configure('Title.TLabel',
                       background=ModernDarkTheme.BACKGROUND,
                       foreground=ModernDarkTheme.TEXT_PRIMARY,
                       font=('Microsoft YaHei', 14, 'bold'))
        
        style.configure('Subtitle.TLabel',
                       background=ModernDarkTheme.BACKGROUND,
                       foreground=ModernDarkTheme.TEXT_SECONDARY,
                       font=('Microsoft YaHei', 11))
        
        style.configure('Primary.TButton',
                       background=ModernDarkTheme.PRIMARY,
                       foreground=ModernDarkTheme.TEXT_PRIMARY,
                       font=('Microsoft YaHei', 10, 'bold'),
                       borderwidth=0,
                       focuscolor='none')
        
        style.map('Primary.TButton',
                 background=[('active', ModernDarkTheme.PRIMARY_HOVER)])
        
        style.configure('Secondary.TButton',
                       background=ModernDarkTheme.CARD_BACKGROUND,
                       foreground=ModernDarkTheme.TEXT_PRIMARY,
                       font=('Microsoft YaHei', 10),
                       borderwidth=1,
                       bordercolor=ModernDarkTheme.BORDER,
                       focuscolor='none')
        
        style.configure('Dark.TEntry',
                       fieldbackground=ModernDarkTheme.INPUT_BACKGROUND,
                       foreground=ModernDarkTheme.TEXT_PRIMARY,
                       borderwidth=2,
                       bordercolor=ModernDarkTheme.BORDER,
                       insertcolor=ModernDarkTheme.TEXT_PRIMARY,
                       font=('Microsoft YaHei', 10))
        
        style.configure('Dark.TCombobox',
                       fieldbackground=ModernDarkTheme.INPUT_BACKGROUND,
                       foreground=ModernDarkTheme.TEXT_PRIMARY,
                       borderwidth=2,
                       bordercolor=ModernDarkTheme.BORDER,
                       font=('Microsoft YaHei', 10))
        
    def create_widgets(self):
        """
        创建所有界面组件
        """
        # 主容器
        main_frame = ttk.Frame(self.root, style='Dark.TFrame')
        main_frame.pack(fill='both', expand=True, padx=20, pady=20)
        
        # 创建各个区域
        self.create_url_section(main_frame)
        self.create_video_info_section(main_frame)
        self.create_download_settings_section(main_frame)
        self.create_control_buttons_section(main_frame)
        self.create_log_section(main_frame)
        
    def create_url_section(self, parent):
        """
        创建URL输入区域
        """
        # 标题
        url_label = ttk.Label(parent, text="视频链接", style='Title.TLabel')
        url_label.pack(anchor='w', pady=(0, 10))
        
        # URL输入框架
        url_frame = ttk.Frame(parent, style='Card.TFrame')
        url_frame.pack(fill='x', pady=(0, 20), ipady=15, ipadx=15)
        
        # URL输入框
        self.url_var = tk.StringVar()
        self.url_entry = ttk.Entry(url_frame, 
                                  textvariable=self.url_var,
                                  style='Dark.TEntry',
                                  font=('Microsoft YaHei', 11),
                                  width=60)
        self.url_entry.pack(side='left', fill='x', expand=True, padx=(0, 10))
        self.url_entry.insert(0, "请粘贴B站视频链接...")
        
        # 获取信息按钮
        self.get_info_btn = ttk.Button(url_frame,
                                      text="获取信息",
                                      style='Primary.TButton',
                                      command=self.get_video_info)
        self.get_info_btn.pack(side='right')
        
    def create_video_info_section(self, parent):
        """
        创建视频信息区域
        """
        # 标题
        info_label = ttk.Label(parent, text="视频信息", style='Title.TLabel')
        info_label.pack(anchor='w', pady=(0, 10))
        
        # 视频信息框架
        info_frame = ttk.Frame(parent, style='Card.TFrame')
        info_frame.pack(fill='x', pady=(0, 20), ipady=15, ipadx=15)
        
        # 左侧封面区域
        cover_frame = ttk.Frame(info_frame, style='Card.TFrame')
        cover_frame.pack(side='left', padx=(0, 15))
        
        self.cover_label = tk.Label(cover_frame,
                                   text="📹\n封面",
                                   width=20, height=8,
                                   bg=ModernDarkTheme.CARD_BACKGROUND,
                                   fg=ModernDarkTheme.TEXT_SECONDARY,
                                   font=('Microsoft YaHei', 12),
                                   relief='solid',
                                   borderwidth=1)
        self.cover_label.pack()
        
        # 右侧信息区域
        details_frame = ttk.Frame(info_frame, style='Dark.TFrame')
        details_frame.pack(side='left', fill='both', expand=True)
        
        # 视频标题
        self.title_label = ttk.Label(details_frame,
                                    text="等待获取视频信息...",
                                    style='Title.TLabel',
                                    wraplength=500)
        self.title_label.pack(anchor='w', pady=(0, 8))
        
        # UP主信息
        self.author_label = ttk.Label(details_frame,
                                     text="",
                                     style='Subtitle.TLabel')
        self.author_label.pack(anchor='w', pady=(0, 5))
        
        # 视频时长
        self.duration_label = ttk.Label(details_frame,
                                       text="",
                                       style='Dark.TLabel')
        self.duration_label.pack(anchor='w', pady=(0, 10))
        
        # 清晰度选择
        quality_frame = ttk.Frame(details_frame, style='Dark.TFrame')
        quality_frame.pack(anchor='w', fill='x')
        
        quality_label = ttk.Label(quality_frame,
                                 text="清晰度:",
                                 style='Dark.TLabel')
        quality_label.pack(side='left', padx=(0, 10))
        
        self.quality_var = tk.StringVar()
        self.quality_combo = ttk.Combobox(quality_frame,
                                         textvariable=self.quality_var,
                                         style='Dark.TCombobox',
                                         state='disabled',
                                         width=20)
        self.quality_combo.pack(side='left')
        
    def create_download_settings_section(self, parent):
        """
        创建下载设置区域
        """
        # 标题
        settings_label = ttk.Label(parent, text="下载设置", style='Title.TLabel')
        settings_label.pack(anchor='w', pady=(0, 10))
        
        # 设置框架
        settings_frame = ttk.Frame(parent, style='Card.TFrame')
        settings_frame.pack(fill='x', pady=(0, 20), ipady=15, ipadx=15)
        
        # 下载路径
        path_frame = ttk.Frame(settings_frame, style='Dark.TFrame')
        path_frame.pack(fill='x')
        
        path_label = ttk.Label(path_frame,
                              text="下载至:",
                              style='Dark.TLabel',
                              width=8)
        path_label.pack(side='left', padx=(0, 10))
        
        self.path_var = tk.StringVar(value=self.download_path)
        self.path_entry = ttk.Entry(path_frame,
                                   textvariable=self.path_var,
                                   style='Dark.TEntry',
                                   state='readonly',
                                   font=('Microsoft YaHei', 10))
        self.path_entry.pack(side='left', fill='x', expand=True, padx=(0, 10))
        
        self.browse_btn = ttk.Button(path_frame,
                                    text="📁 浏览...",
                                    style='Secondary.TButton',
                                    command=self.browse_path)
        self.browse_btn.pack(side='right')
        
    def create_control_buttons_section(self, parent):
        """
        创建控制按钮区域
        """
        # 按钮框架
        buttons_frame = ttk.Frame(parent, style='Dark.TFrame')
        buttons_frame.pack(fill='x', pady=(0, 20))
        
        # 居中容器
        center_frame = ttk.Frame(buttons_frame, style='Dark.TFrame')
        center_frame.pack(expand=True)
        
        # 开始下载按钮
        self.download_btn = ttk.Button(center_frame,
                                      text="🚀 开始下载",
                                      style='Primary.TButton',
                                      command=self.start_download,
                                      state='disabled',
                                      width=15)
        self.download_btn.pack(side='left', padx=(0, 10))
        
        # 暂停按钮
        self.pause_btn = ttk.Button(center_frame,
                                   text="⏸️ 暂停",
                                   style='Secondary.TButton',
                                   command=self.pause_download,
                                   state='disabled',
                                   width=12)
        self.pause_btn.pack(side='left', padx=(0, 10))
        
        # 停止按钮
        self.stop_btn = ttk.Button(center_frame,
                                  text="⏹️ 停止",
                                  style='Secondary.TButton',
                                  command=self.stop_download,
                                  state='disabled',
                                  width=12)
        self.stop_btn.pack(side='left')
        
        # 进度条
        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(parent,
                                           variable=self.progress_var,
                                           maximum=100,
                                           length=400,
                                           mode='determinate')
        # 初始隐藏进度条
        
    def create_log_section(self, parent):
        """
        创建日志区域
        """
        # 日志标题框架
        log_header = ttk.Frame(parent, style='Dark.TFrame')
        log_header.pack(fill='x', pady=(0, 10))
        
        log_title = ttk.Label(log_header, text="下载日志", style='Title.TLabel')
        log_title.pack(side='left')
        
        self.clear_log_btn = ttk.Button(log_header,
                                       text="🗑️ 清空日志",
                                       style='Secondary.TButton',
                                       command=self.clear_log)
        self.clear_log_btn.pack(side='right')
        
        # 日志文本区域
        log_frame = ttk.Frame(parent, style='Card.TFrame')
        log_frame.pack(fill='both', expand=True, ipady=10, ipadx=10)
        
        self.log_text = scrolledtext.ScrolledText(log_frame,
                                                  height=12,
                                                  bg=ModernDarkTheme.BACKGROUND,
                                                  fg=ModernDarkTheme.TEXT_PRIMARY,
                                                  font=('Consolas', 10),
                                                  insertbackground=ModernDarkTheme.TEXT_PRIMARY,
                                                  selectbackground=ModernDarkTheme.PRIMARY,
                                                  relief='flat',
                                                  borderwidth=0,
                                                  wrap='word')
        self.log_text.pack(fill='both', expand=True)
        
        # 配置日志颜色标签
        self.log_text.tag_configure('info', foreground=ModernDarkTheme.TEXT_PRIMARY)
        self.log_text.tag_configure('success', foreground=ModernDarkTheme.SUCCESS)
        self.log_text.tag_configure('warning', foreground=ModernDarkTheme.WARNING)
        self.log_text.tag_configure('error', foreground=ModernDarkTheme.ERROR)
        
        # 添加初始日志
        self.add_log("系统启动完成，等待用户操作...", "info")
        
    def setup_bindings(self):
        """
        设置事件绑定
        """
        # URL输入框事件
        self.url_entry.bind('<FocusIn>', self.on_url_focus_in)
        self.url_entry.bind('<FocusOut>', self.on_url_focus_out)
        self.url_entry.bind('<Return>', lambda e: self.get_video_info())
        
        # 窗口关闭事件
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        
    def on_url_focus_in(self, event):
        """
        URL输入框获得焦点
        """
        if self.url_var.get() == "请粘贴B站视频链接...":
            self.url_var.set("")
            
    def on_url_focus_out(self, event):
        """
        URL输入框失去焦点
        """
        if not self.url_var.get().strip():
            self.url_var.set("请粘贴B站视频链接...")
            
    def get_video_info(self):
        """
        获取视频信息
        """
        url = self.url_var.get().strip()
        if not url or url == "请粘贴B站视频链接...":
            self.add_log("请输入视频链接", "warning")
            return
            
        if not validate_bilibili_url(url):
            self.add_log("请输入有效的B站视频链接", "error")
            return
            
        self.add_log(f"正在获取视频信息: {url}", "info")
        self.get_info_btn.configure(text="获取中...", state='disabled')
        
        # 异步获取视频信息
        def fetch_info():
            try:
                # 解析URL
                parsed_info = self.api.parse_video_url(url)
                if not parsed_info:
                    self.root.after(0, lambda: self.on_video_info_error("无法解析视频URL"))
                    return
                
                # 获取视频信息
                video_info = self.api.get_video_info(parsed_info['video_id'])
                if not video_info:
                    self.root.after(0, lambda: self.on_video_info_error("无法获取视频信息"))
                    return
                
                # 获取视频流信息
                # 首先需要从视频信息中获取对应分P的cid
                page_num = parsed_info.get('page', 1)
                cid = None
                for page in video_info.get('pages', []):
                    if page.get('page') == page_num:
                        cid = page.get('cid')
                        break
                
                if not cid:
                    self.root.after(0, lambda: self.on_video_info_error("无法获取视频分P信息"))
                    return
                
                stream_info = self.api.get_video_stream_info(parsed_info['video_id'], cid)
                if not stream_info:
                    self.root.after(0, lambda: self.on_video_info_error("无法获取视频流信息"))
                    return
                
                self.current_video_info = {
                    'parsed_info': parsed_info,
                    'video_info': video_info,
                    'stream_info': stream_info
                }
                
                self.root.after(0, self.on_video_info_success)
                
            except Exception as e:
                self.root.after(0, lambda: self.on_video_info_error(f"获取视频信息失败: {str(e)}"))
            
        threading.Thread(target=fetch_info, daemon=True).start()
        
    def on_video_info_success(self):
        """
        视频信息获取成功
        """
        if not self.current_video_info:
            return
            
        video_info = self.current_video_info['video_info']
        stream_info = self.current_video_info['stream_info']
        
        # 更新视频信息
        title = video_info.get('title', '未知标题')
        author = video_info.get('owner', {}).get('name', '未知UP主')
        duration = video_info.get('duration', 0)
        
        # 格式化时长
        hours = duration // 3600
        minutes = (duration % 3600) // 60
        seconds = duration % 60
        if hours > 0:
            duration_str = f"{hours}:{minutes:02d}:{seconds:02d}"
        else:
            duration_str = f"{minutes}:{seconds:02d}"
        
        self.title_label.configure(text=title)
        self.author_label.configure(text=f"UP主: {author}")
        self.duration_label.configure(text=f"时长: {duration_str}")
        
        # 更新清晰度选项
        quality_options = []
        quality_map = {}
        
        accept_quality = stream_info.get('accept_quality', [])
        accept_description = stream_info.get('accept_description', [])
        
        for i, quality_id in enumerate(accept_quality):
            quality_desc = accept_description[i] if i < len(accept_description) else f'质量{quality_id}'
            quality_options.append(quality_desc)
            quality_map[quality_desc] = quality_id
        
        if not quality_options:
            quality_options = ['默认画质']
            quality_map['默认画质'] = 80
        
        self.quality_combo.configure(state='normal')
        self.quality_combo['values'] = quality_options
        self.quality_combo.current(0)
        self.quality_combo.configure(state='readonly')
        
        # 保存质量映射
        self.quality_map = quality_map
        
        # 恢复按钮状态
        self.get_info_btn.configure(text="获取信息", state='normal')
        self.download_btn.configure(state='normal')
        
        self.add_log(f"视频信息获取成功: {title}", "success")
        
    def on_video_info_error(self, error_msg):
        """
        视频信息获取失败
        """
        self.get_info_btn.configure(text="获取信息", state='normal')
        self.add_log(error_msg, "error")
        
    def browse_path(self):
        """
        浏览下载路径
        """
        folder = filedialog.askdirectory(
            title="选择下载文件夹",
            initialdir=self.download_path
        )
        
        if folder:
            self.download_path = folder
            self.path_var.set(folder)
            self.add_log(f"下载路径已更改为: {folder}", "info")
            
    def start_download(self):
        """
        开始下载
        """
        if not self.current_video_info:
            self.add_log("请先获取视频信息", "warning")
            return
            
        if not self.quality_var.get():
            self.add_log("请选择视频质量", "warning")
            return
            
        # 获取选择的质量
        selected_quality_desc = self.quality_var.get()
        quality_id = getattr(self, 'quality_map', {}).get(selected_quality_desc, 80)
        
        # 创建下载任务
        video_info = self.current_video_info['video_info']
        parsed_info = self.current_video_info['parsed_info']
        
        # 生成安全的文件名
        title = video_info.get('title', '未知视频')
        safe_title = "".join(c for c in title if c.isalnum() or c in (' ', '-', '_')).rstrip()
        filename = f"{safe_title}.mp4"
        
        # 创建下载任务
        task_id = self.downloader.create_download_task(
            url=parsed_info['original_url'],
            save_path=self.download_path,
            filename=filename
        )
        
        if not task_id:
            self.add_log("创建下载任务失败", "error")
            return
            
        self.current_task_id = task_id
        
        # 设置进度回调
        task = self.downloader.tasks[task_id]
        task.set_progress_callback(self.on_download_progress)
        task.set_completion_callback(self.on_download_complete)
        
        # 更新UI状态
        self.is_downloading = True
        self.download_btn.configure(state='disabled')
        self.pause_btn.configure(state='normal')
        self.stop_btn.configure(state='normal')
        
        # 显示进度条
        self.progress_bar.pack(fill='x', pady=(10, 0))
        self.progress_var.set(0)
        
        self.add_log(f"开始下载视频: {title}", "info")
        self.add_log(f"清晰度: {selected_quality_desc}", "info")
        self.add_log(f"保存路径: {self.download_path}", "info")
        
        # 开始下载
        page = parsed_info.get('page', 1)
        success = self.downloader.start_download(task_id, quality_id, page)
        
        if not success:
            self.add_log("启动下载失败", "error")
            self.reset_download_ui()
        
    def on_download_progress(self, progress):
        """
        下载进度回调
        """
        def update_ui():
            # 更新进度条
            self.progress_var.set(progress.percentage)
            
            # 更新日志
            if progress.total_size > 0:
                downloaded_mb = progress.downloaded_size / (1024 * 1024)
                total_mb = progress.total_size / (1024 * 1024)
                speed_text = format_speed(progress.speed) if hasattr(progress, 'speed') else "--"
                
                log_msg = f"下载进度: {progress.percentage:.1f}% ({downloaded_mb:.1f}MB/{total_mb:.1f}MB) 速度: {speed_text}"
                self.add_log(log_msg, "info")
            else:
                self.add_log(f"下载进度: {progress.percentage:.1f}%", "info")
        
        # 在主线程中更新UI
        self.root.after(0, update_ui)
        
    def on_download_complete(self, task_id, success):
        """
        下载完成回调
        """
        def update_ui():
            if success:
                self.add_log("下载完成！", "success")
                # 显示文件保存位置
                if self.current_task_id and self.current_task_id in self.downloader.tasks:
                    task = self.downloader.tasks[self.current_task_id]
                    file_path = task.save_path / task.filename
                    self.add_log(f"文件已保存至: {file_path}", "success")
            else:
                self.add_log("下载失败！", "error")
            
            self.reset_download_ui()
        
        # 在主线程中更新UI
        self.root.after(0, update_ui)
        
    def reset_download_ui(self):
        """
        重置下载UI状态
        """
        self.is_downloading = False
        self.download_progress = 0
        self.current_task_id = None
        
        self.download_btn.configure(state='normal')
        self.pause_btn.configure(state='disabled')
        self.stop_btn.configure(state='disabled')
        
        # 隐藏进度条
        self.progress_bar.pack_forget()
        self.progress_var.set(0)
        
    def pause_download(self):
        """
        暂停下载
        """
        if self.current_task_id and self.current_task_id in self.downloader.tasks:
            task = self.downloader.tasks[self.current_task_id]
            if task.is_active():
                task.pause()
                self.download_btn.configure(state='normal')
                self.pause_btn.configure(state='disabled')
                self.add_log("下载已暂停", "warning")
            elif task.is_paused():
                task.resume()
                self.download_btn.configure(state='disabled')
                self.pause_btn.configure(state='normal')
                self.add_log("下载已恢复", "info")
        
    def stop_download(self):
        """
        停止下载
        """
        if self.current_task_id and self.current_task_id in self.downloader.tasks:
            task = self.downloader.tasks[self.current_task_id]
            task.stop()
            self.add_log("下载已停止", "error")
            self.reset_download_ui()
        
    def clear_log(self):
        """
        清空日志
        """
        self.log_text.delete(1.0, tk.END)
        self.add_log("日志已清空", "info")
        
    def add_log(self, message, log_type="info"):
        """
        添加日志消息
        """
        import datetime
        
        timestamp = datetime.datetime.now().strftime("%H:%M:%S")
        formatted_message = f"[{timestamp}] {message}\n"
        
        self.log_text.insert(tk.END, formatted_message, log_type)
        self.log_text.see(tk.END)
        
    def on_closing(self):
        """
        窗口关闭事件
        """
        if self.is_downloading:
            if messagebox.askquestion("确认退出", "正在下载中，确定要退出吗？") == 'no':
                return
                
        self.root.destroy()
        
    def run(self):
        """
        启动应用程序
        """
        self.root.mainloop()

def main():
    """
    主函数
    """
    print("🚀 B站视频下载器 Tkinter版本")
    print("=" * 40)
    print("版本: v2.0.0")
    print("UI框架: Tkinter (Python内置)")
    print("主题: 现代化深色主题")
    print("=" * 40)
    
    try:
        app = BilibiliDownloaderTk()
        app.run()
    except Exception as e:
        print(f"应用程序启动失败: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main()